home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / hplip / base / device.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  62.1 KB  |  2,244 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import socket
  5. import re
  6. import gzip
  7. import os.path as os
  8. import time
  9. import urllib
  10. import StringIO
  11. import httplib
  12. import struct
  13. from g import *
  14. from codes import *
  15. import utils
  16. import status
  17. import pml
  18. from prnt import pcl, ldl, cups
  19. import models
  20. import mdns
  21. import slp
  22. from strings import StringTable
  23.  
  24. try:
  25.     import hpmudext
  26. except ImportError:
  27.     if not os.getenv('HPLIP_BUILD'):
  28.         log.error('HPMUDEXT could not be loaded. Please check HPLIP installation.')
  29.         sys.exit(1)
  30.     
  31. except:
  32.     not os.getenv('HPLIP_BUILD')
  33.  
  34. dbus_avail = False
  35. dbus_disabled = False
  36.  
  37. try:
  38.     import dbus
  39.     from dbus import lowlevel, SessionBus
  40.     dbus_avail = True
  41. except ImportError:
  42.     log.warn('python-dbus not installed.')
  43.  
  44. DEFAULT_PROBE_BUS = [
  45.     'usb',
  46.     'par',
  47.     'cups']
  48. VALID_BUSES = ('par', 'net', 'cups', 'usb')
  49. VALID_BUSES_WO_CUPS = ('par', 'net', 'usb')
  50. DEFAULT_FILTER = None
  51. VALID_FILTERS = ('print', 'scan', 'fax', 'pcard', 'copy')
  52. DEFAULT_BE_FILTER = ('hp',)
  53. pat_deviceuri = re.compile('(.*):/(.*?)/(\\S*?)\\?(?:serial=(\\S*)|device=(\\S*)|ip=(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}[^&]*))(?:&port=(\\d))?', re.IGNORECASE)
  54. http_pat_url = re.compile('/(.*?)/(\\S*?)\\?(?:serial=(\\S*)|device=(\\S*))&loc=(\\S*)', re.IGNORECASE)
  55. direct_pat = re.compile('direct (.*?) "(.*?)" "(.*?)" "(.*?)"', re.IGNORECASE)
  56. pat_dynamic_ctr = re.compile('CTR:\\d*\\s.*;', re.IGNORECASE)
  57. MAX_BUFFER = 8192
  58. model_dat = models.ModelData()
  59. ip_pat = re.compile('\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b', re.IGNORECASE)
  60. dev_pat = re.compile('/dev/.+', re.IGNORECASE)
  61. usb_pat = re.compile('(\\d+):(\\d+)', re.IGNORECASE)
  62.  
  63. class Event(object):
  64.     
  65.     def __init__(self, device_uri, printer_name, event_code, username = prop.username, job_id = 0, title = '', timedate = 0):
  66.         self.device_uri = unicode(utils.xrstrip(device_uri, '\x00'))[:64].encode('utf-8')
  67.         self.printer_name = unicode(utils.xrstrip(printer_name, '\x00'))[:64].encode('utf-8')
  68.         self.event_code = int(event_code)
  69.         self.username = unicode(utils.xrstrip(username, '\x00'))[:32].encode('utf-8')
  70.         self.job_id = int(job_id)
  71.         self.title = unicode(utils.xrstrip(title, '\x00'))[:64].encode('utf-8')
  72.         if timedate:
  73.             self.timedate = float(timedate)
  74.         else:
  75.             self.timedate = time.time()
  76.         self.pipe_fmt = '64s64sI32sI64sf'
  77.         self.dbus_fmt = 'ssisisd'
  78.  
  79.     
  80.     def debug(self):
  81.         log.debug('    device_uri=%s' % self.device_uri)
  82.         log.debug('    printer_name=%s' % self.printer_name)
  83.         log.debug('    event_code=%d' % self.event_code)
  84.         log.debug('    username=%s' % self.username)
  85.         log.debug('    job_id=%d' % self.job_id)
  86.         log.debug('    title=%s' % self.title)
  87.         log.debug('    timedate=%s' % self.timedate)
  88.  
  89.     
  90.     def pack_for_pipe(self):
  91.         return struct.pack(self.pipe_fmt, self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate)
  92.  
  93.     
  94.     def send_via_pipe(self, fd, recipient = 'hpssd'):
  95.         if fd is not None:
  96.             log.debug('Sending event %d to %s (via pipe %d)...' % (self.event_code, recipient, fd))
  97.             
  98.             try:
  99.                 os.write(fd, self.pack_for_pipe())
  100.                 return True
  101.             except OSError:
  102.                 log.debug('Failed.')
  103.                 return False
  104.             
  105.  
  106.         None<EXCEPTION MATCH>OSError
  107.  
  108.     
  109.     def send_via_dbus(self, session_bus, interface = 'com.hplip.StatusService'):
  110.         if session_bus is not None and dbus_avail:
  111.             log.debug('Sending event %d to %s (via dbus)...' % (self.event_code, interface))
  112.             msg = lowlevel.SignalMessage('/', interface, 'Event')
  113.             msg.append(signature = self.dbus_fmt, *self.as_tuple())
  114.             session_bus.send_message(msg)
  115.         
  116.  
  117.     
  118.     def copy(self):
  119.         return Event(*self.as_tuple())
  120.  
  121.     
  122.     def __str__(self):
  123.         return "<Event('%s', '%s', %d, '%s', %d, '%s', %f)>" % self.as_tuple()
  124.  
  125.     
  126.     def as_tuple(self):
  127.         return (self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate)
  128.  
  129.  
  130.  
  131. class FaxEvent(Event):
  132.     
  133.     def __init__(self, temp_file, event):
  134.         Event.__init__(self, *event.as_tuple())
  135.         self.temp_file = temp_file
  136.         self.pipe_fmt = '64s64sI32sI64sfs'
  137.         self.dbus_fmt = 'ssisisfs'
  138.  
  139.     
  140.     def debug(self):
  141.         log.debug('FAX:')
  142.         Event.debug(self)
  143.         log.debug('    temp_file=%s' % self.temp_file)
  144.  
  145.     
  146.     def __str__(self):
  147.         return "<FaxEvent('%s', '%s', %d, '%s', %d, '%s', %f, '%s')>" % self.as_tuple()
  148.  
  149.     
  150.     def as_tuple(self):
  151.         return (self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate, self.temp_file)
  152.  
  153.  
  154.  
  155. class DeviceIOEvent(Event):
  156.     
  157.     def __init__(self, bytes_written, event):
  158.         Event.__init__(self, *event.as_tuple())
  159.         self.bytes_written = bytes_written
  160.         self.pipe_fmt = '64s64sI32sI64sfI'
  161.         self.dbus_fmt = 'ssisisfi'
  162.  
  163.     
  164.     def debug(self):
  165.         log.debug('DEVIO:')
  166.         Event.debug(self)
  167.         log.debug('    bytes_written=%d' % self.bytes_written)
  168.  
  169.     
  170.     def __str__(self):
  171.         return "<DeviceIOEvent('%s', '%s', %d, '%s', %d, '%s', %f, '%d')>" % self.as_tuple()
  172.  
  173.     
  174.     def as_tuple(self):
  175.         return (self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate, self.bytes_written)
  176.  
  177.  
  178.  
  179. def init_dbus(dbus_loop = None):
  180.     global dbus_avail, dbus_avail, dbus_avail, dbus_avail, dbus_avail
  181.     service = None
  182.     session_bus = None
  183.     if not prop.gui_build:
  184.         dbus_avail = False
  185.         return (dbus_avail, None, None)
  186.     if dbus_avail and not dbus_disabled:
  187.         if os.getuid() == 0:
  188.             log.debug('Not starting dbus: running as root.')
  189.             dbus_avail = False
  190.             return (dbus_avail, None, None)
  191.         
  192.         try:
  193.             if dbus_loop is None:
  194.                 session_bus = dbus.SessionBus()
  195.             else:
  196.                 session_bus = dbus.SessionBus(dbus_loop)
  197.         except dbus.exceptions.DBusException:
  198.             os.getuid() == 0
  199.             e = os.getuid() == 0
  200.             prop.gui_build
  201.             if os.getuid() != 0:
  202.                 log.error('Unable to connect to dbus session bus.')
  203.             else:
  204.                 log.debug('Unable to connect to dbus session bus (running as root?)')
  205.             dbus_avail = False
  206.             return (dbus_avail, None, None)
  207.  
  208.         
  209.         try:
  210.             log.debug('Connecting to com.hplip.StatusService (try #1)...')
  211.             service = session_bus.get_object('com.hplip.StatusService', '/com/hplip/StatusService')
  212.             dbus_avail = True
  213.         except dbus.exceptions.DBusException:
  214.             os.getuid() == 0
  215.             e = os.getuid() == 0
  216.             prop.gui_build
  217.             
  218.             try:
  219.                 os.waitpid(-1, os.WNOHANG)
  220.             except OSError:
  221.                 pass
  222.  
  223.             path = utils.which('hp-systray')
  224.             log.debug('Running hp-systray: %s --force-startup' % path)
  225.             os.spawnlp(os.P_NOWAIT, path, 'hp-systray', '--force-startup')
  226.             log.debug('Waiting for hp-systray to start...')
  227.             time.sleep(1)
  228.             t = 2
  229.             while True:
  230.                 
  231.                 try:
  232.                     log.debug('Connecting to com.hplip.StatusService (try #%d)...' % t)
  233.                     service = session_bus.get_object('com.hplip.StatusService', '/com/hplip/StatusService')
  234.                 except dbus.exceptions.DBusException:
  235.                     None if path else os.path.exists(path)
  236.                     e = None if path else os.path.exists(path)
  237.                     log.debug('Unable to connect to dbus. Is hp-systray running?')
  238.                     t += 1
  239.                     if t > 5:
  240.                         log.warn('Unable to connect to dbus. Is hp-systray running?')
  241.                         return (False, None, None)
  242.                     time.sleep(1)
  243.                     continue
  244.                     t > 5
  245.  
  246.                 log.debug('Connected.')
  247.                 dbus_avail = True
  248.                 break
  249.                 continue
  250.                 None if path else os.path.exists(path)
  251.         except:
  252.             os.getuid() == 0<EXCEPTION MATCH>dbus.exceptions.DBusException
  253.         
  254.  
  255.     os.getuid() == 0
  256.     return (dbus_avail, service, session_bus)
  257.  
  258.  
  259. def makeURI(param, port = 1):
  260.     (cups_uri, sane_uri, fax_uri) = ('', '', '')
  261.     found = False
  262.     
  263.     try:
  264.         param = socket.gethostbyname(param)
  265.     except socket.gaierror:
  266.         log.debug('Gethostbyname() failed. Trying other patterns...')
  267.  
  268.     if dev_pat.search(param) is not None:
  269.         log.debug('Trying parallel with %s' % param)
  270.         (result_code, uri) = hpmudext.make_par_uri(param)
  271.         if result_code == hpmudext.HPMUD_R_OK and uri:
  272.             log.debug('Found: %s' % uri)
  273.             found = True
  274.             cups_uri = uri
  275.         else:
  276.             log.debug('Not found.')
  277.     elif usb_pat.search(param) is not None:
  278.         match_obj = usb_pat.search(param)
  279.         usb_bus_id = match_obj.group(1)
  280.         usb_dev_id = match_obj.group(2)
  281.         log.debug('Trying USB with bus=%s dev=%s...' % (usb_bus_id, usb_dev_id))
  282.         (result_code, uri) = hpmudext.make_usb_uri(usb_bus_id, usb_dev_id)
  283.         if result_code == ERROR_SUCCESS and uri:
  284.             log.debug('Found: %s' % uri)
  285.             found = True
  286.             cups_uri = uri
  287.         else:
  288.             log.debug('Not found.')
  289.     elif ip_pat.search(param) is not None:
  290.         log.debug('Trying IP address %s' % param)
  291.         (result_code, uri) = hpmudext.make_net_uri(param, port)
  292.         if result_code == hpmudext.HPMUD_R_OK and uri:
  293.             log.debug('Found: %s' % uri)
  294.             found = True
  295.             cups_uri = uri
  296.         else:
  297.             log.debug('Not found.')
  298.     else:
  299.         log.debug('Trying serial number %s' % param)
  300.         devices = probeDevices(bus = [
  301.             'usb',
  302.             'par'])
  303.         for d in devices:
  304.             log.debug(d)
  305.             
  306.             try:
  307.                 (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(d)
  308.             except Error:
  309.                 continue
  310.  
  311.             if bus == 'par':
  312.                 mq = queryModelByURI(d)
  313.                 (result_code, device_id) = hpmudext.device_open(d, mq.get('io-mode', hpmudext.HPMUD_UNI_MODE))
  314.                 if result_code == hpmudext.HPMUD_R_OK:
  315.                     (result_code, data) = hpmudext.get_device_id(device_id)
  316.                     serial = parseDeviceID(data).get('SN', '')
  317.                     hpmudext.close_device(device_id)
  318.                 
  319.             
  320.             if serial.lower() == param.lower():
  321.                 log.debug('Found: %s' % d)
  322.                 found = True
  323.                 cups_uri = d
  324.                 break
  325.                 continue
  326.             log.debug('Not found.')
  327.         
  328.     if found:
  329.         
  330.         try:
  331.             mq = queryModelByURI(cups_uri)
  332.         except Error:
  333.             e = None
  334.             log.error('Error: %s' % e.msg)
  335.             (cups_uri, sane_uri, fax_uri) = ('', '', '')
  336.  
  337.         if mq.get('support-type', SUPPORT_TYPE_NONE) > SUPPORT_TYPE_NONE:
  338.             if mq.get('scan-type', 0):
  339.                 sane_uri = cups_uri.replace('hp:', 'hpaio:')
  340.             
  341.             if mq.get('fax-type', 0):
  342.                 fax_uri = cups_uri.replace('hp:', 'hpfax:')
  343.             
  344.         else:
  345.             (cups_uri, sane_uri, fax_uri) = ('', '', '')
  346.     else:
  347.         (scan_uri, fax_uri) = ('', '')
  348.     if cups_uri:
  349.         user_conf.set('last_used', 'device_uri', cups_uri)
  350.     
  351.     return (cups_uri, sane_uri, fax_uri)
  352.  
  353.  
  354. def queryModelByModel(model):
  355.     model = models.normalizeModelName(model).lower()
  356.     return model_dat[model]
  357.  
  358.  
  359. def queryModelByURI(device_uri):
  360.     
  361.     try:
  362.         (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(device_uri)
  363.     except Error:
  364.         raise Error(ERROR_INVALID_DEVICE_URI)
  365.  
  366.     return queryModelByModel(model)
  367.  
  368.  
  369. def probeDevices(bus = DEFAULT_PROBE_BUS, timeout = 10, ttl = 4, filter = DEFAULT_FILTER, search = '', net_search = 'slp', back_end_filter = ('hp',)):
  370.     num_devices = 0
  371.     ret_devices = { }
  372.     if search:
  373.         
  374.         try:
  375.             search_pat = re.compile(search, re.IGNORECASE)
  376.         log.error('Invalid search pattern. Search uses standard regular expressions. For more info, see: http://www.amk.ca/python/howto/regex/')
  377.         search = ''
  378.  
  379.     
  380.     for b in bus:
  381.         log.debug('Probing bus: %s' % b)
  382.         if b not in VALID_BUSES:
  383.             log.error('Invalid bus: %s' % b)
  384.             continue
  385.         
  386.         if b == 'net':
  387.             if net_search == 'slp':
  388.                 
  389.                 try:
  390.                     detected_devices = slp.detectNetworkDevices(ttl, timeout)
  391.                 except Error:
  392.                     socket.error = None
  393.                     log.error('An error occured during network probe.')
  394.                     raise ERROR_INTERNAL
  395.                 except:
  396.                     None<EXCEPTION MATCH>Error
  397.                 
  398.  
  399.             None<EXCEPTION MATCH>Error
  400.             
  401.             try:
  402.                 detected_devices = mdns.detectNetworkDevices(ttl, timeout)
  403.             except Error:
  404.                 socket.error = None
  405.                 log.error('An error occured during network probe.')
  406.                 raise ERROR_INTERNAL
  407.  
  408.             for ip in detected_devices:
  409.                 update_spinner()
  410.                 hn = detected_devices[ip].get('hn', '?UNKNOWN?')
  411.                 num_devices_on_jd = detected_devices[ip].get('num_devices', 0)
  412.                 num_ports_on_jd = detected_devices[ip].get('num_ports', 1)
  413.                 if num_devices_on_jd > 0:
  414.                     for port in range(num_ports_on_jd):
  415.                         dev = detected_devices[ip].get('device%d' % (port + 1), '0')
  416.                         if dev is not None and dev != '0':
  417.                             device_id = parseDeviceID(dev)
  418.                             model = models.normalizeModelName(device_id.get('MDL', '?UNKNOWN?'))
  419.                             if num_ports_on_jd == 1:
  420.                                 device_uri = 'hp:/net/%s?ip=%s' % (model, ip)
  421.                             else:
  422.                                 device_uri = 'hp:/net/%s?ip=%s&port=%d' % (model, ip, port + 1)
  423.                             include = True
  424.                             mq = queryModelByModel(model)
  425.                             if not mq:
  426.                                 log.debug('Not found.')
  427.                                 include = False
  428.                             elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
  429.                                 log.debug('Not supported.')
  430.                                 include = False
  431.                             elif filter not in (None, 'print', 'print-type'):
  432.                                 include = __checkFilter(filter, mq)
  433.                             
  434.                             if include:
  435.                                 ret_devices[device_uri] = (model, model, hn)
  436.                             
  437.                         include
  438.                     
  439.             
  440.         if b in ('usb', 'par'):
  441.             if b == 'par':
  442.                 bn = hpmudext.HPMUD_BUS_PARALLEL
  443.             else:
  444.                 bn = hpmudext.HPMUD_BUS_USB
  445.             (result_code, data) = hpmudext.probe_devices(bn)
  446.             if result_code == hpmudext.HPMUD_R_OK:
  447.                 for x in data.splitlines():
  448.                     m = direct_pat.match(x)
  449.                     if not m.group(1):
  450.                         pass
  451.                     uri = ''
  452.                     if not m.group(2):
  453.                         pass
  454.                     mdl = ''
  455.                     if not m.group(3):
  456.                         pass
  457.                     desc = ''
  458.                     if not m.group(4):
  459.                         pass
  460.                     devid = ''
  461.                     log.debug(uri)
  462.                     
  463.                     try:
  464.                         (back_end, is_hp, bb, model, serial, dev_file, host, port) = parseDeviceURI(uri)
  465.                     except Error:
  466.                         continue
  467.  
  468.                     include = True
  469.                     if mdl and uri and is_hp:
  470.                         mq = queryModelByModel(model)
  471.                         if not mq:
  472.                             log.debug('Not found.')
  473.                             include = False
  474.                         elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
  475.                             log.debug('Not supported.')
  476.                             include = False
  477.                         elif filter not in (None, 'print', 'print-type'):
  478.                             include = __checkFilter(filter, mq)
  479.                         
  480.                         if include:
  481.                             ret_devices[uri] = (mdl, desc, devid)
  482.                         
  483.                     include
  484.                 
  485.             
  486.         result_code == hpmudext.HPMUD_R_OK
  487.         if b == 'cups':
  488.             cups_printers = cups.getPrinters()
  489.             x = len(cups_printers)
  490.             for p in cups_printers:
  491.                 device_uri = p.device_uri
  492.                 log.debug('%s: %s' % (device_uri, p.name))
  493.                 if device_uri != '':
  494.                     
  495.                     try:
  496.                         (back_end, is_hp, bs, model, serial, dev_file, host, port) = parseDeviceURI(device_uri)
  497.                     except Error:
  498.                         log.debug('Unrecognized URI: %s' % device_uri)
  499.                         continue
  500.  
  501.                     if not is_hp:
  502.                         continue
  503.                     
  504.                     include = True
  505.                     mq = queryModelByModel(model)
  506.                     if not mq:
  507.                         include = False
  508.                         log.debug('Not found.')
  509.                     elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
  510.                         log.debug('Not supported.')
  511.                         include = False
  512.                     elif filter not in (None, 'print', 'print-type'):
  513.                         include = __checkFilter(filter, mq)
  514.                     
  515.                     if include:
  516.                         ret_devices[device_uri] = (model, model, '')
  517.                     
  518.                 include
  519.             
  520.     
  521.     probed_devices = { }
  522.     for uri in ret_devices:
  523.         num_devices += 1
  524.         (mdl, model, devid_or_hn) = ret_devices[uri]
  525.         include = True
  526.         if search:
  527.             match_obj = search_pat.search('%s %s %s %s' % (mdl, model, devid_or_hn, uri))
  528.             if match_obj is None:
  529.                 log.debug("%s %s %s %s: Does not match search '%s'." % (mdl, model, devid_or_hn, uri, search))
  530.                 include = False
  531.             
  532.         
  533.         if include:
  534.             probed_devices[uri] = ret_devices[uri]
  535.             continue
  536.     
  537.     cleanup_spinner()
  538.     return probed_devices
  539.  
  540.  
  541. def getSupportedCUPSDevices(back_end_filter = [
  542.     'hp'], filter = DEFAULT_FILTER):
  543.     devices = { }
  544.     printers = cups.getPrinters()
  545.     for p in printers:
  546.         
  547.         try:
  548.             (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(p.device_uri)
  549.         except Error:
  550.             continue
  551.  
  552.         if (back_end_filter == '*' and back_end in back_end_filter or 'hpaio' in back_end_filter or back_end == 'hp') and model and is_hp:
  553.             include = True
  554.             mq = queryModelByModel(model)
  555.             if not mq:
  556.                 log.debug('Not found.')
  557.                 include = False
  558.             elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
  559.                 log.debug('Not supported.')
  560.                 include = False
  561.             elif filter not in (None, 'print', 'print-type'):
  562.                 include = __checkFilter(filter, mq)
  563.             
  564.             if include:
  565.                 if 'hpaio' in back_end_filter:
  566.                     d = p.device_uri.replace('hp:', 'hpaio:')
  567.                 else:
  568.                     d = p.device_uri
  569.                 
  570.                 try:
  571.                     devices[d]
  572.                 except KeyError:
  573.                     devices[d] = [
  574.                         p.name]
  575.  
  576.                 devices[d].append(p.name)
  577.             
  578.         include
  579.     
  580.     return devices
  581.  
  582.  
  583. def getSupportedCUPSPrinters(back_end_filter = [
  584.     'hp'], filter = DEFAULT_FILTER):
  585.     printer_list = []
  586.     printers = cups.getPrinters()
  587.     for p in printers:
  588.         
  589.         try:
  590.             (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(p.device_uri)
  591.         except Error:
  592.             continue
  593.  
  594.         if (back_end_filter == '*' or back_end in back_end_filter) and model and is_hp:
  595.             include = True
  596.             mq = queryModelByModel(model)
  597.             if not mq:
  598.                 log.debug('Not found.')
  599.                 include = False
  600.             elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
  601.                 log.debug('Not supported.')
  602.                 include = False
  603.             elif filter not in (None, 'print', 'print-type'):
  604.                 include = __checkFilter(filter, mq)
  605.             
  606.             if include:
  607.                 p.name = p.name.decode('utf-8')
  608.                 printer_list.append(p)
  609.             
  610.         include
  611.     
  612.     return printer_list
  613.  
  614.  
  615. def getSupportedCUPSPrinterNames(back_end_filter = [
  616.     'hp'], filter = DEFAULT_FILTER):
  617.     printers = getSupportedCUPSPrinters(back_end_filter, filter)
  618.     return [ p.name for p in printers ]
  619.  
  620.  
  621. def getDeviceURIByPrinterName(printer_name, scan_uri_flag = False):
  622.     if printer_name is None:
  623.         return None
  624.     device_uri = None
  625.     printers = cups.getPrinters()
  626.     for p in printers:
  627.         
  628.         try:
  629.             (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(p.device_uri)
  630.         except Error:
  631.             printer_name is None
  632.             printer_name is None
  633.             continue
  634.         except:
  635.             printer_name is None
  636.  
  637.         if is_hp and p.name == printer_name:
  638.             if scan_uri_flag:
  639.                 device_uri = p.device_uri.replace('hp:', 'hpaio:')
  640.             else:
  641.                 device_uri = p.device_uri
  642.             break
  643.             continue
  644.     
  645.     return device_uri
  646.  
  647.  
  648. def parseDeviceID(device_id):
  649.     d = { }
  650.     x = _[1]
  651.     for z in x:
  652.         y = z.split(':')
  653.         
  654.         try:
  655.             d.setdefault(y[0].strip(), y[1])
  656.         continue
  657.         except IndexError:
  658.             []
  659.             []
  660.             []
  661.             d.setdefault(y[0].strip(), None)
  662.             continue
  663.         
  664.  
  665.     
  666.     d.setdefault('MDL', '')
  667.     d.setdefault('SN', '')
  668.     if 'SERIAL' in d:
  669.         d['SN'] = d['SERIAL']
  670.         del d['SERIAL']
  671.     elif 'SERN' in d:
  672.         d['SN'] = d['SERN']
  673.         del d['SERN']
  674.     
  675.     if d['SN'].startswith('X'):
  676.         d['SN'] = ''
  677.     
  678.     return d
  679.  
  680.  
  681. def parseDynamicCounter(ctr_field, convert_to_int = True):
  682.     (counter, value) = ctr_field.split(' ')
  683.     
  684.     try:
  685.         if not utils.xlstrip(str(counter), '0'):
  686.             pass
  687.         counter = int('0')
  688.         if convert_to_int:
  689.             if not utils.xlstrip(str(value), '0'):
  690.                 pass
  691.             value = int('0')
  692.     except ValueError:
  693.         if convert_to_int:
  694.             (counter, value) = (0, 0)
  695.         else:
  696.             (counter, value) = (0, '')
  697.     except:
  698.         convert_to_int
  699.  
  700.     return (counter, value)
  701.  
  702.  
  703. def parseDeviceURI(device_uri):
  704.     m = pat_deviceuri.match(device_uri)
  705.     if m is None:
  706.         log.debug('Device URI %s is invalid/unknown' % device_uri)
  707.         raise Error(ERROR_INVALID_DEVICE_URI)
  708.     m is None
  709.     if not m.group(1).lower():
  710.         pass
  711.     back_end = ''
  712.     is_hp = back_end in ('hp', 'hpfax', 'hpaio')
  713.     if not m.group(2).lower():
  714.         pass
  715.     bus = ''
  716.     if bus not in ('usb', 'net', 'bt', 'fw', 'par'):
  717.         log.debug('Device URI %s is invalid/unknown' % device_uri)
  718.         raise Error(ERROR_INVALID_DEVICE_URI)
  719.     bus not in ('usb', 'net', 'bt', 'fw', 'par')
  720.     if not m.group(3):
  721.         pass
  722.     model = ''
  723.     if not m.group(4):
  724.         pass
  725.     serial = ''
  726.     if not m.group(5):
  727.         pass
  728.     dev_file = ''
  729.     if not m.group(6):
  730.         pass
  731.     host = ''
  732.     if not m.group(7):
  733.         pass
  734.     port = 1
  735.     if bus == 'net':
  736.         
  737.         try:
  738.             port = int(port)
  739.         except (ValueError, TypeError):
  740.             port = 1
  741.  
  742.         if port == 0:
  743.             port = 1
  744.         
  745.     
  746.     return (back_end, is_hp, bus, model, serial, dev_file, host, port)
  747.  
  748.  
  749. def isLocal(bus):
  750.     return bus in ('par', 'usb', 'fw', 'bt')
  751.  
  752.  
  753. def isNetwork(bus):
  754.     return bus in ('net',)
  755.  
  756.  
  757. def __checkFilter(filter, mq):
  758.     for f, p in filter.items():
  759.         if f is not None:
  760.             (op, val) = p
  761.             if not op(mq[f], val):
  762.                 return False
  763.             continue
  764.         op(mq[f], val)
  765.     
  766.     return True
  767.  
  768.  
  769. def validateBusList(bus, allow_cups = True):
  770.     for b in bus:
  771.         if allow_cups:
  772.             vb = VALID_BUSES
  773.         else:
  774.             vb = VALID_BUSES_WO_CUPS
  775.         if b not in vb:
  776.             log.error('Invalid bus name: %s' % b)
  777.             return False
  778.     
  779.     return True
  780.  
  781.  
  782. def validateFilterList(filter):
  783.     if filter is None:
  784.         return True
  785.     for f in filter:
  786.         if f not in VALID_FILTERS:
  787.             log.error("Invalid term '%s' in filter list" % f)
  788.             return False
  789.     
  790.     return True
  791.  
  792. inter_pat = re.compile('%(.*)%', re.IGNORECASE)
  793. st = StringTable()
  794. strings_init = False
  795.  
  796. def initStrings():
  797.     global strings_init
  798.     strings_init = True
  799.     cycles = 0
  800.     while True:
  801.         found = False
  802.         for s in st.string_table:
  803.             (short_string, long_string) = st.string_table[s]
  804.             short_replace = short_string
  805.             long_replace = long_string
  806.             
  807.             try:
  808.                 short_match = inter_pat.match(short_string).group(1)
  809.             except (AttributeError, TypeError):
  810.                 short_match = None
  811.  
  812.             if short_match is not None:
  813.                 found = True
  814.                 
  815.                 try:
  816.                     (short_replace, dummy) = st.string_table[short_match]
  817.                 except KeyError:
  818.                     log.error('String interpolation error: %s' % short_match)
  819.                 except:
  820.                     None<EXCEPTION MATCH>KeyError
  821.                 
  822.  
  823.             None<EXCEPTION MATCH>KeyError
  824.             
  825.             try:
  826.                 long_match = inter_pat.match(long_string).group(1)
  827.             except (AttributeError, TypeError):
  828.                 long_match = None
  829.  
  830.             if long_match is not None:
  831.                 found = True
  832.                 
  833.                 try:
  834.                     (dummy, long_replace) = st.string_table[long_match]
  835.                 except KeyError:
  836.                     log.error('String interpolation error: %s' % long_match)
  837.                 except:
  838.                     None<EXCEPTION MATCH>KeyError
  839.                 
  840.  
  841.             None<EXCEPTION MATCH>KeyError
  842.             if found:
  843.                 st.string_table[s] = (short_replace, long_replace)
  844.                 continue
  845.         
  846.         if not found:
  847.             break
  848.             continue
  849.         cycles += 1
  850.         if cycles > 1000:
  851.             break
  852.             continue
  853.  
  854.  
  855. def queryString(string_id, typ = 0):
  856.     if not strings_init:
  857.         initStrings()
  858.     
  859.     s = st.string_table.get(str(string_id), ('', ''))[typ]
  860.     if type(s) == type(''):
  861.         return s
  862.     return s()
  863.  
  864. AGENT_types = {
  865.     AGENT_TYPE_NONE: 'invalid',
  866.     AGENT_TYPE_BLACK: 'black',
  867.     AGENT_TYPE_CMY: 'cmy',
  868.     AGENT_TYPE_KCM: 'kcm',
  869.     AGENT_TYPE_CYAN: 'cyan',
  870.     AGENT_TYPE_MAGENTA: 'magenta',
  871.     AGENT_TYPE_YELLOW: 'yellow',
  872.     AGENT_TYPE_CYAN_LOW: 'photo_cyan',
  873.     AGENT_TYPE_MAGENTA_LOW: 'photo_magenta',
  874.     AGENT_TYPE_YELLOW_LOW: 'photo_yellow',
  875.     AGENT_TYPE_GGK: 'photo_gray',
  876.     AGENT_TYPE_BLUE: 'photo_blue',
  877.     AGENT_TYPE_KCMY_CM: 'kcmy_cm',
  878.     AGENT_TYPE_LC_LM: 'photo_cyan_and_photo_magenta',
  879.     AGENT_TYPE_LG_PK: 'light_gray_and_photo_black',
  880.     AGENT_TYPE_LG: 'light_gray',
  881.     AGENT_TYPE_G: 'medium_gray',
  882.     AGENT_TYPE_PG: 'photo_gray',
  883.     AGENT_TYPE_C_M: 'cyan_and_magenta',
  884.     AGENT_TYPE_K_Y: 'black_and_yellow',
  885.     AGENT_TYPE_UNSPECIFIED: 'unspecified' }
  886. AGENT_kinds = {
  887.     AGENT_KIND_NONE: 'invalid',
  888.     AGENT_KIND_HEAD: 'head',
  889.     AGENT_KIND_SUPPLY: 'supply',
  890.     AGENT_KIND_HEAD_AND_SUPPLY: 'cartridge',
  891.     AGENT_KIND_TONER_CARTRIDGE: 'toner',
  892.     AGENT_KIND_MAINT_KIT: 'maint_kit',
  893.     AGENT_KIND_ADF_KIT: 'adf_kit',
  894.     AGENT_KIND_DRUM_KIT: 'drum_kit',
  895.     AGENT_KIND_TRANSFER_KIT: 'transfer_kit',
  896.     AGENT_KIND_INT_BATTERY: 'battery',
  897.     AGENT_KIND_UNKNOWN: 'unknown' }
  898. AGENT_healths = {
  899.     AGENT_HEALTH_OK: 'ok',
  900.     AGENT_HEALTH_MISINSTALLED: 'misinstalled',
  901.     AGENT_HEALTH_INCORRECT: 'incorrect',
  902.     AGENT_HEALTH_FAILED: 'failed',
  903.     AGENT_HEALTH_OVERTEMP: 'overtemp',
  904.     AGENT_HEALTH_CHARGING: 'charging',
  905.     AGENT_HEALTH_DISCHARGING: 'discharging' }
  906. AGENT_levels = {
  907.     AGENT_LEVEL_TRIGGER_MAY_BE_LOW: 'low',
  908.     AGENT_LEVEL_TRIGGER_PROBABLY_OUT: 'low',
  909.     AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT: 'out' }
  910. string_cache = { }
  911.  
  912. class Device(object):
  913.     
  914.     def __init__(self, device_uri, printer_name = None, service = None, callback = None, disable_dbus = False):
  915.         global dbus_disabled
  916.         log.debug('Device URI: %s' % device_uri)
  917.         log.debug('Printer: %s' % printer_name)
  918.         dbus_disabled = disable_dbus
  919.         if not disable_dbus:
  920.             if service is None:
  921.                 (self.dbus_avail, self.service, session_bus) = init_dbus()
  922.             else:
  923.                 self.dbus_avail = True
  924.                 self.service = service
  925.         else:
  926.             self.dbus_avail = False
  927.             self.service = None
  928.         self.last_event = None
  929.         printers = cups.getPrinters()
  930.         if device_uri is None and printer_name is not None:
  931.             for p in printers:
  932.                 if p.name.lower() == printer_name.lower():
  933.                     device_uri = p.device_uri
  934.                     log.debug('Device URI: %s' % device_uri)
  935.                     break
  936.                     continue
  937.             else:
  938.                 raise Error(ERROR_DEVICE_NOT_FOUND)
  939.         self.device_uri = device_uri
  940.         self.callback = callback
  941.         self.device_type = DEVICE_TYPE_UNKNOWN
  942.         if self.device_uri is None:
  943.             raise Error(ERROR_DEVICE_NOT_FOUND)
  944.         self.device_uri is None
  945.         if self.device_uri.startswith('hp:'):
  946.             self.device_type = DEVICE_TYPE_PRINTER
  947.         elif self.device_uri.startswith('hpaio:'):
  948.             self.device_type = DEVICE_TYPE_SCANNER
  949.         elif self.device_uri.startswith('hpfax:'):
  950.             self.device_type = DEVICE_TYPE_FAX
  951.         
  952.         
  953.         try:
  954.             (self.back_end, self.is_hp, self.bus, self.model, self.serial, self.dev_file, self.host, self.port) = parseDeviceURI(self.device_uri)
  955.         except Error:
  956.             self.io_state = IO_STATE_NON_HP
  957.             raise Error(ERROR_INVALID_DEVICE_URI)
  958.  
  959.         log.debug('URI: backend=%s, is_hp=%s, bus=%s, model=%s, serial=%s, dev=%s, host=%s, port=%d' % (self.back_end, self.is_hp, self.bus, self.model, self.serial, self.dev_file, self.host, self.port))
  960.         self.model_ui = models.normalizeModelUIName(self.model)
  961.         self.model = models.normalizeModelName(self.model)
  962.         log.debug('Model/UI model: %s/%s' % (self.model, self.model_ui))
  963.         self.mq = { }
  964.         self.dq = { }
  965.         self.icon = 'default_printer'
  966.         self.cups_printers = []
  967.         self.channels = { }
  968.         self.device_id = -1
  969.         self.r_values = None
  970.         self.deviceID = ''
  971.         self.panel_check = True
  972.         self.io_state = IO_STATE_HP_READY
  973.         self.is_local = isLocal(self.bus)
  974.         self.hist = []
  975.         self.supported = False
  976.         self.queryModel()
  977.         if not self.supported:
  978.             log.error('Unsupported model: %s' % self.model)
  979.             self.error_code = STATUS_DEVICE_UNSUPPORTED
  980.             self.sendEvent(self.error_code)
  981.         else:
  982.             self.supported = True
  983.         self.mq.update({
  984.             'model': self.model,
  985.             'model-ui': self.model_ui })
  986.         self.error_state = ERROR_STATE_ERROR
  987.         self.device_state = DEVICE_STATE_NOT_FOUND
  988.         self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND
  989.         for p in printers:
  990.             if self.device_uri == p.device_uri:
  991.                 self.cups_printers.append(p.name)
  992.                 self.state = p.state
  993.                 if self.io_state == IO_STATE_NON_HP:
  994.                     self.model = p.makemodel.split(',')[0]
  995.                 
  996.             self.io_state == IO_STATE_NON_HP
  997.         
  998.         
  999.         try:
  1000.             self.first_cups_printer = self.cups_printers[0]
  1001.         except IndexError:
  1002.             self.first_cups_printer = ''
  1003.  
  1004.         if self.mq.get('fax-type', FAX_TYPE_NONE) != FAX_TYPE_NONE:
  1005.             self.dq.update({
  1006.                 'fax-uri': self.device_uri.replace('hp:/', 'hpfax:/').replace('hpaio:/', 'hpfax:/') })
  1007.         
  1008.         if self.mq.get('scan-type', SCAN_TYPE_NONE) != SCAN_TYPE_NONE:
  1009.             self.dq.update({
  1010.                 'scan-uri': self.device_uri.replace('hp:/', 'hpaio:/').replace('hpfax:/', 'hpaio:/') })
  1011.         
  1012.         self.dq.update({
  1013.             'back-end': self.back_end,
  1014.             'is-hp': self.is_hp,
  1015.             'serial': self.serial,
  1016.             'dev-file': self.dev_file,
  1017.             'host': self.host,
  1018.             'port': self.port,
  1019.             'cups-printer': ','.join(self.cups_printers),
  1020.             'status-code': self.status_code,
  1021.             'status-desc': '',
  1022.             'deviceid': '',
  1023.             'panel': 0,
  1024.             'panel-line1': '',
  1025.             'panel-line2': '',
  1026.             'device-state': self.device_state,
  1027.             'error-state': self.error_state,
  1028.             'device-uri': self.device_uri,
  1029.             'cups-uri': self.device_uri.replace('hpfax:/', 'hp:/').replace('hpaio:/', 'hp:/') })
  1030.         self.device_vars = {
  1031.             'URI': self.device_uri,
  1032.             'DEVICE_URI': self.device_uri,
  1033.             'SCAN_URI': self.device_uri.replace('hp:', 'hpaio:'),
  1034.             'SANE_URI': self.device_uri.replace('hp:', 'hpaio:'),
  1035.             'FAX_URI': self.device_uri.replace('hp:', 'hpfax:'),
  1036.             'PRINTER': self.first_cups_printer,
  1037.             'HOME': prop.home_dir }
  1038.  
  1039.     
  1040.     def sendEvent(self, event_code, printer_name = '', job_id = 0, title = ''):
  1041.         if self.dbus_avail and self.service is not None:
  1042.             
  1043.             try:
  1044.                 log.debug('Sending event %d to hpssd...' % event_code)
  1045.                 self.service.SendEvent(self.device_uri, printer_name, event_code, prop.username, job_id, title)
  1046.             except dbus.exceptions.DBusException:
  1047.                 e = None
  1048.                 log.debug('dbus call to SendEvent() failed.')
  1049.             except:
  1050.                 None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1051.             
  1052.  
  1053.         None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1054.  
  1055.     
  1056.     def quit(self):
  1057.         pass
  1058.  
  1059.     
  1060.     def queryModel(self):
  1061.         if not self.mq:
  1062.             self.mq = queryModelByURI(self.device_uri)
  1063.         
  1064.         self.supported = bool(self.mq)
  1065.         if self.supported:
  1066.             for m in self.mq:
  1067.                 self.__dict__[m.replace('-', '_')] = self.mq[m]
  1068.             
  1069.         
  1070.  
  1071.     
  1072.     def queryString(self, string_id):
  1073.         return queryString(string_id)
  1074.  
  1075.     
  1076.     def open(self, open_for_printing = False):
  1077.         if self.supported and self.io_state in (IO_STATE_HP_READY, IO_STATE_HP_NOT_AVAIL):
  1078.             prev_device_state = self.device_state
  1079.             self.io_state = IO_STATE_HP_NOT_AVAIL
  1080.             self.device_state = DEVICE_STATE_NOT_FOUND
  1081.             self.error_state = ERROR_STATE_ERROR
  1082.             self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND
  1083.             self.device_id = -1
  1084.             self.open_for_printing = open_for_printing
  1085.             if open_for_printing:
  1086.                 log.debug('Opening device: %s (for printing)' % self.device_uri)
  1087.                 self.io_mode = self.mq.get('io-mode', hpmudext.HPMUD_UNI_MODE)
  1088.             else:
  1089.                 log.debug('Opening device: %s (not for printing)' % self.device_uri)
  1090.                 self.io_mode = self.mq.get('io-mfp-mode', hpmudext.HPMUD_UNI_MODE)
  1091.             log.debug('I/O mode=%d' % self.io_mode)
  1092.             (result_code, self.device_id) = hpmudext.open_device(self.device_uri, self.io_mode)
  1093.             if result_code != hpmudext.HPMUD_R_OK:
  1094.                 self.error_state = ERROR_STATE_ERROR
  1095.                 self.error_code = result_code + ERROR_CODE_BASE
  1096.                 self.sendEvent(self.error_code)
  1097.                 if result_code == hpmudext.HPMUD_R_DEVICE_BUSY:
  1098.                     log.error('Device busy: %s' % self.device_uri)
  1099.                 else:
  1100.                     log.error('Unable to communicate with device (code=%d): %s' % (result_code, self.device_uri))
  1101.                 self.last_event = Event(self.device_uri, '', EVENT_ERROR_DEVICE_NOT_FOUND, prop.username, 0, '', time.time())
  1102.                 raise Error(ERROR_DEVICE_NOT_FOUND)
  1103.             result_code != hpmudext.HPMUD_R_OK
  1104.             log.debug('device-id=%d' % self.device_id)
  1105.             self.io_state = IO_STATE_HP_OPEN
  1106.             self.error_state = ERROR_STATE_CLEAR
  1107.             log.debug('Opened device: %s (backend=%s, is_hp=%s, bus=%s, model=%s, dev=%s, serial=%s, host=%s, port=%d)' % (self.back_end, self.device_uri, self.is_hp, self.bus, self.model, self.dev_file, self.serial, self.host, self.port))
  1108.             if prev_device_state == DEVICE_STATE_NOT_FOUND:
  1109.                 self.device_state = DEVICE_STATE_JUST_FOUND
  1110.             else:
  1111.                 self.device_state = DEVICE_STATE_FOUND
  1112.             self.getDeviceID()
  1113.             self.getSerialNumber()
  1114.             return self.device_id
  1115.         self.io_state in (IO_STATE_HP_READY, IO_STATE_HP_NOT_AVAIL)
  1116.  
  1117.     
  1118.     def close(self):
  1119.         if self.io_state == IO_STATE_HP_OPEN:
  1120.             log.debug('Closing device...')
  1121.             if len(self.channels) > 0:
  1122.                 for c in self.channels.keys():
  1123.                     self._Device__closeChannel(c)
  1124.                 
  1125.             
  1126.             result_code = hpmudext.close_device(self.device_id)
  1127.             log.debug('Result-code = %d' % result_code)
  1128.             self.channels.clear()
  1129.             self.io_state = IO_STATE_HP_READY
  1130.         
  1131.  
  1132.     
  1133.     def __openChannel(self, service_name):
  1134.         
  1135.         try:
  1136.             if self.io_state == IO_STATE_HP_OPEN:
  1137.                 if service_name == hpmudext.HPMUD_S_PRINT_CHANNEL and not (self.open_for_printing):
  1138.                     self.close()
  1139.                     self.open(True)
  1140.                 elif service_name != hpmudext.HPMUD_S_PRINT_CHANNEL and self.open_for_printing:
  1141.                     self.close()
  1142.                     self.open(False)
  1143.                 
  1144.             else:
  1145.                 self.open(service_name == hpmudext.HPMUD_S_PRINT_CHANNEL)
  1146.         except:
  1147.             log.error('unable to open channel')
  1148.             return -1
  1149.  
  1150.         service_name = service_name.upper()
  1151.         if service_name not in self.channels:
  1152.             log.debug('Opening %s channel...' % service_name)
  1153.             (result_code, channel_id) = hpmudext.open_channel(self.device_id, service_name)
  1154.             self.channels[service_name] = channel_id
  1155.             log.debug('channel-id=%d' % channel_id)
  1156.             return channel_id
  1157.         return self.channels[service_name]
  1158.  
  1159.     
  1160.     def openChannel(self, service_name):
  1161.         return self._Device__openChannel(service_name)
  1162.  
  1163.     
  1164.     def openPrint(self):
  1165.         return self._Device__openChannel(hpmudext.HPMUD_S_PRINT_CHANNEL)
  1166.  
  1167.     
  1168.     def openFax(self):
  1169.         return self._Device__openChannel(hpmudext.HPMUD_S_FAX_SEND_CHANNEL)
  1170.  
  1171.     
  1172.     def openPCard(self):
  1173.         return self._Device__openChannel(hpmudext.HPMUD_S_MEMORY_CARD_CHANNEL)
  1174.  
  1175.     
  1176.     def openEWS(self):
  1177.         return self._Device__openChannel(hpmudext.HPMUD_S_EWS_CHANNEL)
  1178.  
  1179.     
  1180.     def closePrint(self):
  1181.         return self._Device__closeChannel(hpmudext.HPMUD_S_PRINT_CHANNEL)
  1182.  
  1183.     
  1184.     def closePCard(self):
  1185.         return self._Device__closeChannel(hpmudext.HPMUD_S_MEMORY_CARD_CHANNEL)
  1186.  
  1187.     
  1188.     def closeFax(self):
  1189.         return self._Device__closeChannel(hpmudext.HPMUD_S_FAX_SEND_CHANNEL)
  1190.  
  1191.     
  1192.     def openPML(self):
  1193.         return self._Device__openChannel(hpmudext.HPMUD_S_PML_CHANNEL)
  1194.  
  1195.     
  1196.     def closePML(self):
  1197.         return self._Device__closeChannel(hpmudext.HPMUD_S_PML_CHANNEL)
  1198.  
  1199.     
  1200.     def closeEWS(self):
  1201.         return self._Device__closeChannel(hpmudext.HPMUD_S_EWS_CHANNEL)
  1202.  
  1203.     
  1204.     def openCfgUpload(self):
  1205.         return self._Device__openChannel(hpmudext.HPMUD_S_CONFIG_UPLOAD_CHANNEL)
  1206.  
  1207.     
  1208.     def closeCfgUpload(self):
  1209.         return self._Device__closeChannel(hpmudext.HPMUD_S_CONFIG_UPLOAD_CHANNEL)
  1210.  
  1211.     
  1212.     def openCfgDownload(self):
  1213.         return self._Device__openChannel(hpmudext.HPMUD_S_CONFIG_DOWNLOAD_CHANNEL)
  1214.  
  1215.     
  1216.     def closeCfgDownload(self):
  1217.         return self._Device__closeChannel(hpmudext.HPMUD_S_CONFIG_DOWNLOAD_CHANNEL)
  1218.  
  1219.     
  1220.     def openSoapFax(self):
  1221.         return self._Device__openChannel(hpmudext.HPMUD_S_SOAP_FAX)
  1222.  
  1223.     
  1224.     def closeSoapFax(self):
  1225.         return self._Device__closeChannel(hpmudext.HPMUD_S_SOAP_FAX)
  1226.  
  1227.     
  1228.     def __closeChannel(self, service_name):
  1229.         if self.io_state == IO_STATE_HP_OPEN:
  1230.             service_name = service_name.upper()
  1231.             if service_name in self.channels:
  1232.                 log.debug('Closing %s channel...' % service_name)
  1233.                 result_code = hpmudext.close_channel(self.device_id, self.channels[service_name])
  1234.                 del self.channels[service_name]
  1235.             
  1236.         
  1237.  
  1238.     
  1239.     def closeChannel(self, service_name):
  1240.         return self._Device__closeChannel(service_name)
  1241.  
  1242.     
  1243.     def getDeviceID(self):
  1244.         needs_close = False
  1245.         if self.io_state != IO_STATE_HP_OPEN:
  1246.             
  1247.             try:
  1248.                 self.open()
  1249.             except:
  1250.                 return -1
  1251.  
  1252.             needs_close = True
  1253.         
  1254.         (result_code, data) = hpmudext.get_device_id(self.device_id)
  1255.         if result_code != hpmudext.HPMUD_R_OK:
  1256.             self.raw_deviceID = ''
  1257.             self.deviceID = { }
  1258.         else:
  1259.             self.raw_deviceID = data
  1260.             self.deviceID = parseDeviceID(data)
  1261.         if needs_close:
  1262.             self.close()
  1263.         
  1264.         return self.deviceID
  1265.  
  1266.     
  1267.     def getSerialNumber(self):
  1268.         if self.serial:
  1269.             return None
  1270.         
  1271.         try:
  1272.             self.serial = self.deviceID['SN']
  1273.         except KeyError:
  1274.             self.serial
  1275.             self.serial
  1276.         except:
  1277.             self.serial
  1278.  
  1279.         if self.serial:
  1280.             return None
  1281.         if self.serial is None:
  1282.             self.serial = ''
  1283.         
  1284.  
  1285.     
  1286.     def getThreeBitStatus(self):
  1287.         pass
  1288.  
  1289.     
  1290.     def getStatusFromDeviceID(self):
  1291.         self.getDeviceID()
  1292.         return status.parseStatus(parseDeviceID(self.raw_deviceID))
  1293.  
  1294.     
  1295.     def __parseRValues(self, r_value):
  1296.         r_value_str = str(r_value)
  1297.         r_value_str = ''.join([
  1298.             '0' * (9 - len(r_value_str)),
  1299.             r_value_str])
  1300.         rg = r_value_str[:3]
  1301.         rr = r_value_str[3:]
  1302.         r_value = int(rr)
  1303.         self.r_values = (r_value, r_value_str, rg, rr)
  1304.         return (r_value, r_value_str, rg, rr)
  1305.  
  1306.     
  1307.     def getRValues(self, r_type, status_type, dynamic_counters):
  1308.         (r_value, r_value_str, rg, rr) = (0, '000000000', '000', '000000')
  1309.         if r_type > 0 and dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE:
  1310.             if self.r_values is None:
  1311.                 if self.dbus_avail:
  1312.                     
  1313.                     try:
  1314.                         r_value = int(self.service.GetCachedIntValue(self.device_uri, 'r_value'))
  1315.                     except dbus.exceptions.DBusException:
  1316.                         e = None
  1317.                         log.debug('dbus call to GetCachedIntValue() failed.')
  1318.                         r_value = -1
  1319.                     except:
  1320.                         None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1321.                     
  1322.  
  1323.                 None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1324.                 if r_value != -1:
  1325.                     log.debug('r_value=%d' % r_value)
  1326.                     (r_value, r_value_str, rg, rr) = self._Device__parseRValues(r_value)
  1327.                     return (r_value, r_value_str, rg, rr)
  1328.             
  1329.             if self.r_values is None:
  1330.                 if status_type == STATUS_TYPE_S and self.is_local and dynamic_counters != STATUS_DYNAMIC_COUNTERS_PML_SNMP:
  1331.                     
  1332.                     try:
  1333.                         r_value = self.getDynamicCounter(140)
  1334.                         if r_value is not None:
  1335.                             log.debug('r_value=%d' % r_value)
  1336.                             (r_value, r_value_str, rg, rr) = self._Device__parseRValues(r_value)
  1337.                             if self.dbus_avail:
  1338.                                 
  1339.                                 try:
  1340.                                     self.service.SetCachedIntValue(self.device_uri, 'r_value', r_value)
  1341.                                 except dbus.exceptions.DBusException:
  1342.                                     e = None
  1343.                                     log.debug('dbus call to SetCachedIntValue() failed.')
  1344.                                 except:
  1345.                                     None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1346.                                 
  1347.  
  1348.                             None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1349.                         else:
  1350.                             log.error('Error attempting to read r-value (2).')
  1351.                             r_value = 0
  1352.                     except Error:
  1353.                         log.error('Error attempting to read r-value (1).')
  1354.                         r_value = 0
  1355.                     finally:
  1356.                         self.closePrint()
  1357.  
  1358.                 elif status_type == STATUS_TYPE_S and dynamic_counters == STATUS_DYNAMIC_COUNTERS_PCL or not (self.is_local) or dynamic_counters == STATUS_DYNAMIC_COUNTERS_PML_SNMP:
  1359.                     
  1360.                     try:
  1361.                         (result_code, r_value) = self.getPML(pml.OID_R_SETTING)
  1362.                         if r_value is not None:
  1363.                             log.debug('r_value=%d' % r_value)
  1364.                             (r_value, r_value_str, rg, rr) = self._Device__parseRValues(r_value)
  1365.                             if self.dbus_avail:
  1366.                                 
  1367.                                 try:
  1368.                                     self.service.SetCachedIntValue(self.device_uri, 'r_value', r_value)
  1369.                                 except dbus.exceptions.DBusException:
  1370.                                     e = None
  1371.                                     log.debug('dbus call to SetCachedIntValue() failed.')
  1372.                                 except:
  1373.                                     None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1374.                                 
  1375.  
  1376.                             None<EXCEPTION MATCH>dbus.exceptions.DBusException
  1377.                         else:
  1378.                             r_value = 0
  1379.                     finally:
  1380.                         self.closePML()
  1381.  
  1382.                 
  1383.             else:
  1384.                 (r_value, r_value_str, rg, rr) = self.r_values
  1385.         
  1386.         return (r_value, r_value_str, rg, rr)
  1387.  
  1388.     
  1389.     def __queryFax(self, quick = False, reread_cups_printers = False):
  1390.         io_mode = self.mq.get('io-mode', IO_MODE_UNI)
  1391.         self.status_code = STATUS_PRINTER_IDLE
  1392.         if io_mode != IO_MODE_UNI:
  1393.             if self.device_state != DEVICE_STATE_NOT_FOUND:
  1394.                 if self.tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK):
  1395.                     
  1396.                     try:
  1397.                         self.getDeviceID()
  1398.                     except Error:
  1399.                         e = None
  1400.                         log.error('Error getting device ID.')
  1401.                         self.last_event = Event(self.device_uri, '', ERROR_DEVICE_IO_ERROR, prop.username, 0, '', time.time())
  1402.                         raise Error(ERROR_DEVICE_IO_ERROR)
  1403.                     except:
  1404.                         None<EXCEPTION MATCH>Error
  1405.                     
  1406.  
  1407.                 None<EXCEPTION MATCH>Error
  1408.                 status_desc = self.queryString(self.status_code)
  1409.                 self.dq.update({
  1410.                     'serial': self.serial,
  1411.                     'cups-printer': ','.join(self.cups_printers),
  1412.                     'status-code': self.status_code,
  1413.                     'status-desc': status_desc,
  1414.                     'deviceid': self.raw_deviceID,
  1415.                     'panel': 0,
  1416.                     'panel-line1': '',
  1417.                     'panel-line2': '',
  1418.                     'device-state': self.device_state,
  1419.                     'error-state': self.error_state })
  1420.             
  1421.             log.debug('Fax activity check...')
  1422.             (tx_active, rx_active) = status.getFaxStatus(self)
  1423.             if tx_active:
  1424.                 self.status_code = STATUS_FAX_TX_ACTIVE
  1425.             elif rx_active:
  1426.                 self.status_code = STATUS_FAX_RX_ACTIVE
  1427.             
  1428.             self.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.status_code, ERROR_STATE_CLEAR)
  1429.             self.error_code = self.status_code
  1430.             self.sendEvent(self.error_code)
  1431.             
  1432.             try:
  1433.                 self.dq.update({
  1434.                     'status-desc': self.queryString(self.status_code),
  1435.                     'error-state': self.error_state })
  1436.             except (KeyError, Error):
  1437.                 self.dq.update({
  1438.                     'status-desc': '',
  1439.                     'error-state': ERROR_STATE_CLEAR })
  1440.  
  1441.             if self.panel_check:
  1442.                 self.panel_check = bool(self.mq.get('panel-check-type', 0))
  1443.             
  1444.             status_type = self.mq.get('status-type', STATUS_TYPE_NONE)
  1445.             if self.panel_check and status_type in (STATUS_TYPE_LJ, STATUS_TYPE_S, STATUS_TYPE_VSTATUS) and io_mode != IO_MODE_UNI:
  1446.                 log.debug('Panel check...')
  1447.                 
  1448.                 try:
  1449.                     (self.panel_check, line1, line2) = status.PanelCheck(self)
  1450.                 finally:
  1451.                     self.closePML()
  1452.  
  1453.                 self.dq.update({
  1454.                     'panel': int(self.panel_check),
  1455.                     'panel-line1': line1,
  1456.                     'panel-line2': line2 })
  1457.             
  1458.             if not quick and reread_cups_printers:
  1459.                 self.cups_printers = []
  1460.                 log.debug('Re-reading CUPS printer queue information.')
  1461.                 printers = cups.getPrinters()
  1462.                 for p in printers:
  1463.                     if self.device_uri == p.device_uri:
  1464.                         self.cups_printers.append(p.name)
  1465.                         self.state = p.state
  1466.                         if self.io_state == IO_STATE_NON_HP:
  1467.                             self.model = p.makemodel.split(',')[0]
  1468.                         
  1469.                     self.io_state == IO_STATE_NON_HP
  1470.                 
  1471.                 self.dq.update({
  1472.                     'cups-printer': ','.join(self.cups_printers) })
  1473.                 
  1474.                 try:
  1475.                     self.first_cups_printer = self.cups_printers[0]
  1476.                 except IndexError:
  1477.                     self.first_cups_printer = ''
  1478.                 except:
  1479.                     None<EXCEPTION MATCH>IndexError
  1480.                 
  1481.  
  1482.             None<EXCEPTION MATCH>IndexError
  1483.         
  1484.         for d in self.dq:
  1485.             self.__dict__[d.replace('-', '_')] = self.dq[d]
  1486.         
  1487.         self.last_event = Event(self.device_uri, '', self.status_code, prop.username, 0, '', time.time())
  1488.         log.debug(self.dq)
  1489.  
  1490.     
  1491.     def queryDevice(self, quick = False, reread_cups_printers = False):
  1492.         if not self.supported:
  1493.             self.dq = { }
  1494.             self.last_event = Event(self.device_uri, '', STATUS_DEVICE_UNSUPPORTED, prop.username, 0, '', time.time())
  1495.             return None
  1496.         if self.device_type == DEVICE_TYPE_FAX:
  1497.             return self._Device__queryFax(quick, reread_cups_printers)
  1498.         r_type = self.mq.get('r-type', 0)
  1499.         tech_type = self.mq.get('tech-type', TECH_TYPE_NONE)
  1500.         status_type = self.mq.get('status-type', STATUS_TYPE_NONE)
  1501.         battery_check = self.mq.get('status-battery-check', STATUS_BATTERY_CHECK_NONE)
  1502.         dynamic_counters = self.mq.get('status-dynamic-counters', STATUS_DYNAMIC_COUNTERS_NONE)
  1503.         io_mode = self.mq.get('io-mode', IO_MODE_UNI)
  1504.         io_mfp_mode = self.mq.get('io-mfp-mode', IO_MODE_UNI)
  1505.         status_code = STATUS_UNKNOWN
  1506.         agents = []
  1507.         if self.device_state != DEVICE_STATE_NOT_FOUND:
  1508.             if self.tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK):
  1509.                 
  1510.                 try:
  1511.                     self.getDeviceID()
  1512.                 except Error:
  1513.                     self.device_type == DEVICE_TYPE_FAX
  1514.                     e = self.device_type == DEVICE_TYPE_FAX
  1515.                     self.supported
  1516.                     log.error('Error getting device ID.')
  1517.                     self.last_event = Event(self.device_uri, '', ERROR_DEVICE_IO_ERROR, prop.username, 0, '', time.time())
  1518.                     raise Error(ERROR_DEVICE_IO_ERROR)
  1519.                 except:
  1520.                     self.device_type == DEVICE_TYPE_FAX<EXCEPTION MATCH>Error
  1521.                 
  1522.  
  1523.             self.device_type == DEVICE_TYPE_FAX
  1524.             status_desc = self.queryString(self.status_code)
  1525.             self.dq.update({
  1526.                 'serial': self.serial,
  1527.                 'cups-printer': ','.join(self.cups_printers),
  1528.                 'status-code': self.status_code,
  1529.                 'status-desc': status_desc,
  1530.                 'deviceid': self.raw_deviceID,
  1531.                 'panel': 0,
  1532.                 'panel-line1': '',
  1533.                 'panel-line2': '',
  1534.                 'device-state': self.device_state,
  1535.                 'error-state': self.error_state })
  1536.             status_block = { }
  1537.             if status_type == STATUS_TYPE_NONE:
  1538.                 log.warn('No status available for device.')
  1539.                 status_block = {
  1540.                     'status-code': STATUS_UNKNOWN }
  1541.             elif status_type in (STATUS_TYPE_VSTATUS, STATUS_TYPE_S):
  1542.                 log.debug('Type 1/2 (S: or VSTATUS:) status')
  1543.                 status_block = status.parseStatus(self.deviceID)
  1544.             elif status_type in (STATUS_TYPE_LJ, STATUS_TYPE_PML_AND_PJL):
  1545.                 log.debug('Type 3/9 LaserJet PML(+PJL) status')
  1546.                 status_block = status.StatusType3(self, self.deviceID)
  1547.             elif status_type == STATUS_TYPE_LJ_XML:
  1548.                 log.debug('Type 6: LJ XML')
  1549.                 status_block = status.StatusType6(self)
  1550.             elif status_type == STATUS_TYPE_PJL:
  1551.                 log.debug('Type 8: LJ PJL')
  1552.                 status_block = status.StatusType8(self)
  1553.             else:
  1554.                 log.error('Unimplemented status type: %d' % status_type)
  1555.             if battery_check and io_mode != IO_MODE_UNI:
  1556.                 log.debug('Battery check...')
  1557.                 status.BatteryCheck(self, status_block, battery_check)
  1558.             
  1559.             if status_block:
  1560.                 log.debug(status_block)
  1561.                 self.dq.update(status_block)
  1562.                 
  1563.                 try:
  1564.                     status_block['agents']
  1565.                 except KeyError:
  1566.                     pass
  1567.  
  1568.                 agents = status_block['agents']
  1569.                 del self.dq['agents']
  1570.             
  1571.             status_code = self.dq.get('status-code', STATUS_UNKNOWN)
  1572.             self.error_state = STATUS_TO_ERROR_STATE_MAP.get(status_code, ERROR_STATE_CLEAR)
  1573.             self.error_code = status_code
  1574.             self.sendEvent(self.error_code)
  1575.             
  1576.             try:
  1577.                 self.dq.update({
  1578.                     'status-desc': self.queryString(status_code),
  1579.                     'error-state': self.error_state })
  1580.             except (KeyError, Error):
  1581.                 self.dq.update({
  1582.                     'status-desc': '',
  1583.                     'error-state': ERROR_STATE_CLEAR })
  1584.  
  1585.             r_value = 0
  1586.             if not quick and status_type != STATUS_TYPE_NONE:
  1587.                 if self.panel_check:
  1588.                     self.panel_check = bool(self.mq.get('panel-check-type', 0))
  1589.                 
  1590.                 if self.panel_check and status_type in (STATUS_TYPE_LJ, STATUS_TYPE_S, STATUS_TYPE_VSTATUS) and io_mode != IO_MODE_UNI:
  1591.                     log.debug('Panel check...')
  1592.                     
  1593.                     try:
  1594.                         (self.panel_check, line1, line2) = status.PanelCheck(self)
  1595.                     finally:
  1596.                         self.closePML()
  1597.  
  1598.                     self.dq.update({
  1599.                         'panel': int(self.panel_check),
  1600.                         'panel-line1': line1,
  1601.                         'panel-line2': line2 })
  1602.                 
  1603.                 if dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE and io_mode != IO_MODE_UNI:
  1604.                     (r_value, r_value_str, rg, rr) = self.getRValues(r_type, status_type, dynamic_counters)
  1605.                 else:
  1606.                     (r_value, r_value_str, rg, rr) = (0, '000000000', '000', '000000')
  1607.                 self.dq.update({
  1608.                     'r': r_value,
  1609.                     'rs': r_value_str,
  1610.                     'rg': rg,
  1611.                     'rr': rr })
  1612.             
  1613.             if not quick and reread_cups_printers:
  1614.                 self.cups_printers = []
  1615.                 log.debug('Re-reading CUPS printer queue information.')
  1616.                 printers = cups.getPrinters()
  1617.                 for p in printers:
  1618.                     if self.device_uri == p.device_uri:
  1619.                         self.cups_printers.append(p.name)
  1620.                         self.state = p.state
  1621.                         if self.io_state == IO_STATE_NON_HP:
  1622.                             self.model = p.makemodel.split(',')[0]
  1623.                         
  1624.                     self.io_state == IO_STATE_NON_HP
  1625.                 
  1626.                 self.dq.update({
  1627.                     'cups-printer': ','.join(self.cups_printers) })
  1628.                 
  1629.                 try:
  1630.                     self.first_cups_printer = self.cups_printers[0]
  1631.                 except IndexError:
  1632.                     self.first_cups_printer = ''
  1633.                 except:
  1634.                     None<EXCEPTION MATCH>IndexError
  1635.                 
  1636.  
  1637.             None<EXCEPTION MATCH>IndexError
  1638.             if not quick:
  1639.                 if r_value > 0 and self.mq.get('r%d-agent1-kind' % r_value, 0) == 0:
  1640.                     r_value = 0
  1641.                     self.dq.update({
  1642.                         'r': r_value,
  1643.                         'rs': r_value_str,
  1644.                         'rg': rg,
  1645.                         'rr': rr })
  1646.                 
  1647.                 (a, aa) = (1, 1)
  1648.                 while True:
  1649.                     mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), -1)
  1650.                     if mq_agent_kind == -1:
  1651.                         break
  1652.                     
  1653.                     mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0)
  1654.                     mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '')
  1655.                     found = False
  1656.                     log.debug('Looking for kind=%d, type=%d...' % (mq_agent_kind, mq_agent_type))
  1657.                     for agent in agents:
  1658.                         agent_kind = agent['kind']
  1659.                         agent_type = agent['type']
  1660.                         if agent_kind == mq_agent_kind and agent_type == mq_agent_type:
  1661.                             found = True
  1662.                             break
  1663.                             continue
  1664.                     
  1665.                     if found:
  1666.                         log.debug('found: r%d-kind%d-type%d' % (r_value, agent_kind, agent_type))
  1667.                         agent_health = agent.get('health', AGENT_HEALTH_OK)
  1668.                         agent_level = agent.get('level', 100)
  1669.                         agent_level_trigger = agent.get('level-trigger', AGENT_LEVEL_TRIGGER_SUFFICIENT_0)
  1670.                         log.debug('health=%d, level=%d, level_trigger=%d, status_code=%d' % (agent_health, agent_level, agent_level_trigger, status_code))
  1671.                         query = 'agent_%s_%s' % (AGENT_types.get(agent_type, 'unknown'), AGENT_kinds.get(agent_kind, 'unknown'))
  1672.                         agent_desc = self.queryString(query)
  1673.                         query = 'agent_health_ok'
  1674.                         if status_code == STATUS_PRINTER_IDLE or status_code == STATUS_PRINTER_OUT_OF_INK:
  1675.                             if (agent_health == AGENT_HEALTH_OK or agent_health == AGENT_HEALTH_FAIR_MODERATE or agent_kind == AGENT_KIND_HEAD) and agent_level_trigger >= AGENT_LEVEL_TRIGGER_MAY_BE_LOW:
  1676.                                 query = 'agent_level_%s' % AGENT_levels.get(agent_level_trigger, 'unknown')
  1677.                                 if tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK):
  1678.                                     code = agent_type + STATUS_PRINTER_LOW_INK_BASE
  1679.                                 else:
  1680.                                     code = agent_type + STATUS_PRINTER_LOW_TONER_BASE
  1681.                                 self.dq['status-code'] = code
  1682.                                 self.dq['status-desc'] = self.queryString(code)
  1683.                                 self.dq['error-state'] = STATUS_TO_ERROR_STATE_MAP.get(code, ERROR_STATE_LOW_SUPPLIES)
  1684.                                 self.error_code = code
  1685.                                 self.sendEvent(self.error_code)
  1686.                                 if agent_level_trigger in (AGENT_LEVEL_TRIGGER_PROBABLY_OUT, AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT):
  1687.                                     query = 'agent_level_out'
  1688.                                 else:
  1689.                                     query = 'agent_level_low'
  1690.                                 agent_health_desc = self.queryString(query)
  1691.                                 self.dq.update({
  1692.                                     'agent%d-kind' % aa: agent_kind,
  1693.                                     'agent%d-type' % aa: agent_type,
  1694.                                     'agent%d-known' % aa: agent.get('known', False),
  1695.                                     'agent%d-sku' % aa: mq_agent_sku,
  1696.                                     'agent%d-level' % aa: agent_level,
  1697.                                     'agent%d-level-trigger' % aa: agent_level_trigger,
  1698.                                     'agent%d-ack' % aa: agent.get('ack', False),
  1699.                                     'agent%d-hp-ink' % aa: agent.get('hp-ink', False),
  1700.                                     'agent%d-health' % aa: agent_health,
  1701.                                     'agent%d-dvc' % aa: agent.get('dvc', 0),
  1702.                                     'agent%d-virgin' % aa: agent.get('virgin', False),
  1703.                                     'agent%d-desc' % aa: agent_desc,
  1704.                                     'agent%d-id' % aa: agent.get('id', 0),
  1705.                                     'agent%d-health-desc' % aa: agent_health_desc })
  1706.                             else:
  1707.                                 query = 'agent_health_%s' % AGENT_healths.get(agent_health, AGENT_HEALTH_OK)
  1708.                                 agent_health_desc = self.queryString(query)
  1709.                                 self.dq.update({
  1710.                                     'agent%d-kind' % aa: agent_kind,
  1711.                                     'agent%d-type' % aa: agent_type,
  1712.                                     'agent%d-known' % aa: False,
  1713.                                     'agent%d-sku' % aa: mq_agent_sku,
  1714.                                     'agent%d-level' % aa: agent_level,
  1715.                                     'agent%d-level-trigger' % aa: agent_level_trigger,
  1716.                                     'agent%d-ack' % aa: False,
  1717.                                     'agent%d-hp-ink' % aa: False,
  1718.                                     'agent%d-health' % aa: agent_health,
  1719.                                     'agent%d-dvc' % aa: 0,
  1720.                                     'agent%d-virgin' % aa: False,
  1721.                                     'agent%d-desc' % aa: agent_desc,
  1722.                                     'agent%d-id' % aa: 0,
  1723.                                     'agent%d-health-desc' % aa: agent_health_desc })
  1724.                         aa += 1
  1725.                     else:
  1726.                         log.debug('Not found: %d' % a)
  1727.                     a += 1
  1728.             
  1729.         else:
  1730.             r_value = 0
  1731.             if r_type > 0 and self.r_values is not None:
  1732.                 r_value = self.r_values[0]
  1733.             
  1734.             if r_value > 0 and self.mq.get('r%d-agent1-kind', 0) == 0:
  1735.                 r_value = 0
  1736.             
  1737.             a = 1
  1738.             while True:
  1739.                 mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), 0)
  1740.                 if mq_agent_kind == 0:
  1741.                     break
  1742.                 
  1743.                 mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0)
  1744.                 mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '')
  1745.                 query = 'agent_%s_%s' % (AGENT_types.get(mq_agent_type, 'unknown'), AGENT_kinds.get(mq_agent_kind, 'unknown'))
  1746.                 agent_desc = self.queryString(query)
  1747.                 self.dq.update({
  1748.                     'agent%d-kind' % a: mq_agent_kind,
  1749.                     'agent%d-type' % a: mq_agent_type,
  1750.                     'agent%d-known' % a: False,
  1751.                     'agent%d-sku' % a: mq_agent_sku,
  1752.                     'agent%d-level' % a: 0,
  1753.                     'agent%d-level-trigger' % a: AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT,
  1754.                     'agent%d-ack' % a: False,
  1755.                     'agent%d-hp-ink' % a: False,
  1756.                     'agent%d-health' % a: AGENT_HEALTH_MISINSTALLED,
  1757.                     'agent%d-dvc' % a: 0,
  1758.                     'agent%d-virgin' % a: False,
  1759.                     'agent%d-health-desc' % a: self.queryString('agent_health_unknown'),
  1760.                     'agent%d-desc' % a: agent_desc,
  1761.                     'agent%d-id' % a: 0 })
  1762.                 a += 1
  1763.         for d in self.dq:
  1764.             self.__dict__[d.replace('-', '_')] = self.dq[d]
  1765.         
  1766.         self.last_event = Event(self.device_uri, '', status_code, prop.username, 0, '', time.time())
  1767.         log.debug(self.dq)
  1768.  
  1769.     
  1770.     def isBusyOrInErrorState(self):
  1771.         
  1772.         try:
  1773.             self.queryDevice(quick = True)
  1774.         except Error:
  1775.             return True
  1776.  
  1777.         return self.error_state in (ERROR_STATE_ERROR, ERROR_STATE_BUSY)
  1778.  
  1779.     
  1780.     def isIdleAndNoError(self):
  1781.         
  1782.         try:
  1783.             self.queryDevice(quick = True)
  1784.         except Error:
  1785.             return False
  1786.  
  1787.         return self.error_state not in (ERROR_STATE_ERROR, ERROR_STATE_BUSY)
  1788.  
  1789.     
  1790.     def getPML(self, oid, desired_int_size = pml.INT_SIZE_INT):
  1791.         channel_id = self.openPML()
  1792.         (result_code, data, typ, pml_result_code) = hpmudext.get_pml(self.device_id, channel_id, pml.PMLToSNMP(oid[0]), oid[1])
  1793.         if pml_result_code > pml.ERROR_MAX_OK:
  1794.             log.debug('PML/SNMP GET %s failed (result code = 0x%x)' % (oid[0], pml_result_code))
  1795.             return (pml_result_code, None)
  1796.         converted_data = pml.ConvertFromPMLDataFormat(data, oid[1], desired_int_size)
  1797.         if log.is_debug():
  1798.             if oid[1] in (pml.TYPE_STRING, pml.TYPE_BINARY):
  1799.                 log.debug('PML/SNMP GET %s (result code = 0x%x) returned:' % (oid[0], pml_result_code))
  1800.                 log.log_data(data)
  1801.             else:
  1802.                 log.debug('PML/SNMP GET %s (result code = 0x%x) returned: %s' % (oid[0], pml_result_code, repr(converted_data)))
  1803.         
  1804.         return (pml_result_code, converted_data)
  1805.  
  1806.     
  1807.     def setPML(self, oid, value):
  1808.         channel_id = self.openPML()
  1809.         value = pml.ConvertToPMLDataFormat(value, oid[1])
  1810.         (result_code, pml_result_code) = hpmudext.set_pml(self.device_id, channel_id, pml.PMLToSNMP(oid[0]), oid[1], value)
  1811.         if log.is_debug():
  1812.             if oid[1] in (pml.TYPE_STRING, pml.TYPE_BINARY):
  1813.                 log.debug('PML/SNMP SET %s (result code = 0x%x) to:' % (oid[0], pml_result_code))
  1814.                 log.log_data(value)
  1815.             else:
  1816.                 log.debug('PML/SNMP SET %s (result code = 0x%x) to: %s' % (oid[0], pml_result_code, repr(value)))
  1817.         
  1818.         return pml_result_code
  1819.  
  1820.     
  1821.     def getDynamicCounter(self, counter, convert_to_int = True):
  1822.         dynamic_counters = self.mq.get('status-dynamic-counters', STATUS_DYNAMIC_COUNTERS_NONE)
  1823.         log.debug('Dynamic counters: %d' % dynamic_counters)
  1824.         if dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE:
  1825.             if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4:
  1826.                 self.printData(ldl.buildResetPacket(), direct = True)
  1827.                 self.printData(ldl.buildDynamicCountersPacket(counter), direct = True)
  1828.             else:
  1829.                 self.printData(pcl.buildDynamicCounter(counter), direct = True)
  1830.             (value, tries, times_seen, sleepy_time, max_tries) = (0, 0, 0, 0.1, 5)
  1831.             time.sleep(0.1)
  1832.             while True:
  1833.                 if self.callback:
  1834.                     self.callback()
  1835.                 
  1836.                 sleepy_time += 0.1
  1837.                 tries += 1
  1838.                 time.sleep(sleepy_time)
  1839.                 self.getDeviceID()
  1840.                 if 'CTR' in self.deviceID and pat_dynamic_ctr.search(self.raw_deviceID) is not None:
  1841.                     (dev_counter, value) = parseDynamicCounter(self.deviceID['CTR'], convert_to_int)
  1842.                     if counter == dev_counter:
  1843.                         self.printData(pcl.buildDynamicCounter(0), direct = True)
  1844.                         if not convert_to_int:
  1845.                             value = '#' + value
  1846.                         
  1847.                         return value
  1848.                 
  1849.                 if tries > max_tries:
  1850.                     if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4:
  1851.                         self.printData(ldl.buildResetPacket())
  1852.                         self.printData(ldl.buildDynamicCountersPacket(counter), direct = True)
  1853.                     else:
  1854.                         self.printData(pcl.buildDynamicCounter(0), direct = True)
  1855.                     return None
  1856.                 if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4:
  1857.                     self.printData(ldl.buildResetPacket())
  1858.                     self.printData(ldl.buildDynamicCountersPacket(counter), direct = True)
  1859.                     continue
  1860.                 tries > max_tries
  1861.                 self.printData(pcl.buildDynamicCounter(counter), direct = True)
  1862.         else:
  1863.             raise Error(ERROR_DEVICE_DOES_NOT_SUPPORT_OPERATION)
  1864.         return dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE
  1865.  
  1866.     
  1867.     def readPrint(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False):
  1868.         return self._Device__readChannel(self.openPrint, bytes_to_read, stream, timeout, allow_short_read)
  1869.  
  1870.     
  1871.     def readPCard(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False):
  1872.         return self._Device__readChannel(self.openPCard, bytes_to_read, stream, timeout, allow_short_read)
  1873.  
  1874.     
  1875.     def readFax(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False):
  1876.         return self._Device__readChannel(self.openFax, bytes_to_read, stream, timeout, allow_short_read)
  1877.  
  1878.     
  1879.     def readCfgUpload(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False):
  1880.         return self._Device__readChannel(self.openCfgUpload, bytes_to_read, stream, timeout, allow_short_read)
  1881.  
  1882.     
  1883.     def readEWS(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = True):
  1884.         return self._Device__readChannel(self.openEWS, bytes_to_read, stream, timeout, allow_short_read)
  1885.  
  1886.     
  1887.     def readSoapFax(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = True):
  1888.         return self._Device__readChannel(self.openSoapFax, bytes_to_read, stream, timeout, allow_short_read)
  1889.  
  1890.     
  1891.     def __readChannel(self, opener, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False):
  1892.         channel_id = opener()
  1893.         log.debug('Reading channel %d...' % channel_id)
  1894.         num_bytes = 0
  1895.         if stream is None:
  1896.             buffer = ''
  1897.         
  1898.         while True:
  1899.             (result_code, data) = hpmudext.read_channel(self.device_id, channel_id, bytes_to_read, timeout)
  1900.             l = len(data)
  1901.             if result_code == hpmudext.HPMUD_R_IO_TIMEOUT:
  1902.                 log.debug('I/O timeout')
  1903.                 break
  1904.             
  1905.             if result_code != hpmudext.HPMUD_R_OK:
  1906.                 log.error('Channel read error')
  1907.                 raise Error(ERROR_DEVICE_IO_ERROR)
  1908.             result_code != hpmudext.HPMUD_R_OK
  1909.             if not l:
  1910.                 log.debug('End of data')
  1911.                 break
  1912.             
  1913.             if stream is None:
  1914.                 buffer = ''.join([
  1915.                     buffer,
  1916.                     data])
  1917.             else:
  1918.                 stream.write(data)
  1919.             num_bytes += l
  1920.             if self.callback is not None:
  1921.                 self.callback()
  1922.             
  1923.             if num_bytes == bytes_to_read:
  1924.                 log.debug('Full read complete.')
  1925.                 break
  1926.             
  1927.             if allow_short_read and num_bytes < bytes_to_read:
  1928.                 log.debug('Allowed short read of %d of %d bytes complete.' % (num_bytes, bytes_to_read))
  1929.                 break
  1930.                 continue
  1931.         if stream is None:
  1932.             log.debug('Returned %d total bytes in buffer.' % num_bytes)
  1933.             return buffer
  1934.         log.debug('Saved %d total bytes to stream.' % num_bytes)
  1935.         return num_bytes
  1936.  
  1937.     
  1938.     def writePrint(self, data):
  1939.         return self._Device__writeChannel(self.openPrint, data)
  1940.  
  1941.     
  1942.     def writePCard(self, data):
  1943.         return self._Device__writeChannel(self.openPCard, data)
  1944.  
  1945.     
  1946.     def writeFax(self, data):
  1947.         return self._Device__writeChannel(self.openFax, data)
  1948.  
  1949.     
  1950.     def writeEWS(self, data):
  1951.         return self._Device__writeChannel(self.openEWS, data)
  1952.  
  1953.     
  1954.     def writeCfgDownload(self, data):
  1955.         return self._Device__writeChannel(self.openCfgDownload, data)
  1956.  
  1957.     
  1958.     def writeSoapFax(self, data):
  1959.         return self._Device__writeChannel(self.openSoapFax, data)
  1960.  
  1961.     
  1962.     def __writeChannel(self, opener, data):
  1963.         channel_id = opener()
  1964.         buffer = data
  1965.         bytes_out = 0
  1966.         total_bytes_to_write = len(data)
  1967.         log.debug('Writing %d bytes to channel %d...' % (total_bytes_to_write, channel_id))
  1968.         while len(buffer) > 0:
  1969.             (result_code, bytes_written) = hpmudext.write_channel(self.device_id, channel_id, buffer[:prop.max_message_len])
  1970.             if result_code != hpmudext.HPMUD_R_OK:
  1971.                 log.error('Channel write error')
  1972.                 raise Error(ERROR_DEVICE_IO_ERROR)
  1973.             result_code != hpmudext.HPMUD_R_OK
  1974.             buffer = buffer[prop.max_message_len:]
  1975.             bytes_out += bytes_written
  1976.             if self.callback is not None:
  1977.                 self.callback()
  1978.                 continue
  1979.         if total_bytes_to_write != bytes_out:
  1980.             raise Error(ERROR_DEVICE_IO_ERROR)
  1981.         total_bytes_to_write != bytes_out
  1982.         return bytes_out
  1983.  
  1984.     
  1985.     def writeEmbeddedPML(self, oid, value, style = 1, direct = True):
  1986.         if style == 1:
  1987.             func = pcl.buildEmbeddedPML2
  1988.         else:
  1989.             func = pcl.buildEmbeddedPML
  1990.         data = func(pcl.buildPCLCmd('&', 'b', 'W', pml.buildEmbeddedPMLSetPacket(oid[0], value, oid[1])))
  1991.         log.log_data(data)
  1992.         self.printData(data, direct = direct, raw = True)
  1993.  
  1994.     
  1995.     def printGzipFile(self, file_name, printer_name = None, direct = False, raw = True, remove = False):
  1996.         return self.printFile(file_name, printer_name, direct, raw, remove)
  1997.  
  1998.     
  1999.     def printParsedGzipPostscript(self, print_file, printer_name = None):
  2000.         
  2001.         try:
  2002.             os.stat(print_file)
  2003.         except OSError:
  2004.             log.error('File not found: %s' % print_file)
  2005.             return None
  2006.  
  2007.         (temp_file_fd, temp_file_name) = utils.make_temp_file()
  2008.         f = gzip.open(print_file, 'r')
  2009.         x = f.readline()
  2010.         while not x.startswith('%PY_BEGIN'):
  2011.             os.write(temp_file_fd, x)
  2012.             x = f.readline()
  2013.         sub_lines = []
  2014.         x = f.readline()
  2015.         while not x.startswith('%PY_END'):
  2016.             sub_lines.append(x)
  2017.             x = f.readline()
  2018.         SUBS = {
  2019.             'VERSION': prop.version,
  2020.             'MODEL': self.model_ui,
  2021.             'URI': self.device_uri,
  2022.             'BUS': self.bus,
  2023.             'SERIAL': self.serial,
  2024.             'IP': self.host,
  2025.             'PORT': self.port,
  2026.             'DEVNODE': self.dev_file }
  2027.         if self.bus == 'net':
  2028.             SUBS['DEVNODE'] = 'n/a'
  2029.         else:
  2030.             SUBS['IP'] = 'n/a'
  2031.             SUBS['PORT'] = 'n/a'
  2032.         for s in sub_lines:
  2033.             os.write(temp_file_fd, s % SUBS)
  2034.         
  2035.         os.write(temp_file_fd, f.read())
  2036.         f.close()
  2037.         os.close(temp_file_fd)
  2038.         self.printFile(temp_file_name, printer_name, direct = False, raw = False, remove = True)
  2039.  
  2040.     
  2041.     def printFile(self, file_name, printer_name = None, direct = False, raw = True, remove = False):
  2042.         is_gzip = os.path.splitext(file_name)[-1].lower() == '.gz'
  2043.         if printer_name is None:
  2044.             
  2045.             try:
  2046.                 printer_name = self.cups_printers[0]
  2047.             except IndexError:
  2048.                 raise Error(ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE)
  2049.             except:
  2050.                 None<EXCEPTION MATCH>IndexError
  2051.             
  2052.  
  2053.         None<EXCEPTION MATCH>IndexError
  2054.         log.debug("Printing file '%s' to queue '%s' (gzip=%s, direct=%s, raw=%s, remove=%s)" % (file_name, printer_name, is_gzip, direct, raw, remove))
  2055.         if direct:
  2056.             if is_gzip:
  2057.                 self.writePrint(gzip.open(file_name, 'r').read())
  2058.             else:
  2059.                 self.writePrint(file(file_name, 'r').read())
  2060.         elif not utils.which('lpr'):
  2061.             lp_opt = ''
  2062.             if raw:
  2063.                 lp_opt = '-oraw'
  2064.             
  2065.             if is_gzip:
  2066.                 c = 'gunzip -c %s | lp -c -d%s %s' % (file_name, printer_name, lp_opt)
  2067.             else:
  2068.                 c = 'lp -c -d%s %s %s' % (printer_name, lp_opt, file_name)
  2069.             log.debug(c)
  2070.             exit_code = os.system(c)
  2071.             if exit_code != 0:
  2072.                 log.error('Print command failed with exit code %d!' % exit_code)
  2073.             
  2074.             if remove:
  2075.                 os.remove(file_name)
  2076.             
  2077.         else:
  2078.             (raw_str, rem_str) = ('', '')
  2079.             if raw:
  2080.                 raw_str = '-o raw'
  2081.             
  2082.             if remove:
  2083.                 rem_str = '-r'
  2084.             
  2085.             if is_gzip:
  2086.                 c = 'gunzip -c %s | lpr %s %s -P%s' % (file_name, raw_str, rem_str, printer_name)
  2087.             else:
  2088.                 c = 'lpr -P%s %s %s %s' % (printer_name, raw_str, rem_str, file_name)
  2089.             log.debug(c)
  2090.             exit_code = os.system(c)
  2091.             if exit_code != 0:
  2092.                 log.error('Print command failed with exit code %d!' % exit_code)
  2093.             
  2094.  
  2095.     
  2096.     def printTestPage(self, printer_name = None):
  2097.         return self.printParsedGzipPostscript(os.path.join(prop.home_dir, 'data', 'ps', 'testpage.ps.gz'), printer_name)
  2098.  
  2099.     
  2100.     def printData(self, data, printer_name = None, direct = True, raw = True):
  2101.         if direct:
  2102.             self.writePrint(data)
  2103.         else:
  2104.             (temp_file_fd, temp_file_name) = utils.make_temp_file()
  2105.             os.write(temp_file_fd, data)
  2106.             os.close(temp_file_fd)
  2107.             self.printFile(temp_file_name, printer_name, False, raw, remove = True)
  2108.  
  2109.     
  2110.     def cancelJob(self, jobid):
  2111.         cups.cancelJob(jobid)
  2112.         self.error_code = STATUS_PRINTER_CANCELING
  2113.         self.sendEvent(self.error_code)
  2114.  
  2115.     
  2116.     def queryHistory(self):
  2117.         result = []
  2118.         if self.dbus_avail:
  2119.             
  2120.             try:
  2121.                 (device_uri, history) = self.service.GetHistory(self.device_uri)
  2122.             except dbus.exceptions.DBusException:
  2123.                 e = None
  2124.                 log.error('dbus call to GetHistory() failed.')
  2125.                 return []
  2126.  
  2127.             history.reverse()
  2128.             for h in history:
  2129.                 result.append(Event(*tuple(h)))
  2130.             
  2131.             
  2132.             try:
  2133.                 self.error_code = result[0].event_code
  2134.             except IndexError:
  2135.                 self.error_code = STATUS_UNKNOWN
  2136.  
  2137.             self.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.error_code, ERROR_STATE_CLEAR)
  2138.         else:
  2139.             self.error_code = STATUS_UNKNOWN
  2140.             self.error_state = ERROR_STATE_CLEAR
  2141.         self.hist = result
  2142.         return result
  2143.  
  2144.     
  2145.     def getEWSUrl(self, url, stream):
  2146.         
  2147.         try:
  2148.             if self.is_local:
  2149.                 url2 = '%s&loc=%s' % (self.device_uri.replace('hpfax:', 'hp:'), url)
  2150.                 data = self
  2151.             else:
  2152.                 url2 = 'http://%s%s' % (self.host, url)
  2153.                 data = None
  2154.             log.debug('Opening: %s' % url2)
  2155.             opener = LocalOpener({ })
  2156.             
  2157.             try:
  2158.                 f = opener.open(url2, data)
  2159.             except Error:
  2160.                 log.error('Status read failed: %s' % url2)
  2161.                 stream.seek(0)
  2162.                 stream.truncate()
  2163.  
  2164.             
  2165.             try:
  2166.                 stream.write(f.read())
  2167.             finally:
  2168.                 f.close()
  2169.  
  2170.         finally:
  2171.             self.closeEWS()
  2172.  
  2173.  
  2174.     
  2175.     def downloadFirmware(self, usb_bus_id = None, usb_device_id = None):
  2176.         ok = False
  2177.         filename = os.path.join(prop.data_dir, 'firmware', self.model.lower() + '.fw.gz')
  2178.         log.debug(filename)
  2179.         if os.path.exists(filename):
  2180.             log.debug("Downloading firmware file '%s'..." % filename)
  2181.             
  2182.             try:
  2183.                 self.openPrint()
  2184.                 bytes_written = self.writePrint(gzip.open(filename).read())
  2185.                 log.debug('%s bytes downloaded.' % utils.commafy(bytes_written))
  2186.                 self.closePrint()
  2187.                 ok = True
  2188.                 log.debug('OK')
  2189.             except Error:
  2190.                 e = None
  2191.                 log.error('An error occured: %s' % e.msg)
  2192.             except:
  2193.                 None<EXCEPTION MATCH>Error
  2194.             
  2195.  
  2196.         None<EXCEPTION MATCH>Error
  2197.         log.error("Firmware file '%s' not found." % filename)
  2198.         return ok
  2199.  
  2200.  
  2201.  
  2202. class xStringIO(StringIO.StringIO):
  2203.     
  2204.     def makefile(self, x, y):
  2205.         return self
  2206.  
  2207.  
  2208.  
  2209. class LocalOpener(urllib.URLopener):
  2210.     
  2211.     def open_hp(self, url, dev):
  2212.         log.debug('open_hp(%s)' % url)
  2213.         match_obj = http_pat_url.search(url)
  2214.         if not match_obj.group(1):
  2215.             pass
  2216.         bus = ''
  2217.         if not match_obj.group(2):
  2218.             pass
  2219.         model = ''
  2220.         if not match_obj.group(3):
  2221.             pass
  2222.         serial = ''
  2223.         if not match_obj.group(4):
  2224.             pass
  2225.         device = ''
  2226.         if not match_obj.group(5):
  2227.             pass
  2228.         loc = ''
  2229.         dev.openEWS()
  2230.         dev.writeEWS('GET %s HTTP/1.0\nContent-Length:0\nHost:localhost\nUser-Agent:hplip\n\n' % loc)
  2231.         reply = xStringIO()
  2232.         while dev.readEWS(8192, reply, timeout = 1):
  2233.             pass
  2234.         reply.seek(0)
  2235.         log.log_data(reply.getvalue())
  2236.         response = httplib.HTTPResponse(reply)
  2237.         response.begin()
  2238.         if response.status != httplib.OK:
  2239.             raise Error(ERROR_DEVICE_STATUS_NOT_AVAILABLE)
  2240.         response.status != httplib.OK
  2241.         return response.fp
  2242.  
  2243.  
  2244.